/* -------------------------------------------------------------------------
 *
 * assert.h
 *
 *
 * Portions Copyright (c) 2020 Huawei Technologies Co.,Ltd.
 * Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
 * Portions Copyright (c) 1994, Regents of the University of California
 * Portions Copyright (c) 2010-2012 Postgres-XC Development Group
 *
 * $PostgreSQL$
 *
 * -------------------------------------------------------------------------
 */
#ifndef GTM_ASSERT_H
#define GTM_ASSERT_H

#include "c.h"

extern THR_LOCAL bool assert_enabled;

/*
 * USE_ASSERT_CHECKING, if defined, turns on all the assertions.
 * - plai  9/5/90
 *
 * It should _NOT_ be defined in releases or in benchmark copies
 */

/*
 * Trap
 *		Generates an exception if the given condition is true.
 */
#define Trap(condition, errorType)                                                         \
    do {                                                                                   \
        if ((assert_enabled) && (condition))                                               \
            ExceptionalCondition(CppAsString(condition), (errorType), __FILE__, __LINE__); \
    } while (0)

/*
 *	TrapMacro is the same as Trap but it's intended for use in macros:
 *
 *		#define foo(x) (AssertMacro(x != 0) && bar(x))
 *
 *	Isn't CPP fun?
 */
#define TrapMacro(condition, errorType)          \
    ((bool)((!assert_enabled) || !(condition) || \
            (ExceptionalCondition(CppAsString(condition), (errorType), __FILE__, __LINE__))))
#ifdef PC_LINT
#define Assert(condition)       \
    do {                        \
        if (!(bool)(condition)) \
            exit(1);            \
    } while (0)
#define AssertMacro Assert
#define AssertArg Assert
#define DBG_ASSERT Assert
#define AssertState Assert
#else

#ifndef USE_ASSERT_CHECKING
#define Assert(condition)
#define AssertMacro(condition) ((void)true)
#define AssertArg(condition)
#define AssertState(condition)
#else
#define Assert(condition) Trap(!(condition), "FailedAssertion")

#define AssertMacro(condition) ((void)TrapMacro(!(condition), "FailedAssertion"))

#define AssertArg(condition) Trap(!(condition), "BadArgument")

#define AssertState(condition) Trap(!(condition), "BadState")
#endif  /* USE_ASSERT_CHECKING */
#endif  // PC_LINT
extern int ExceptionalCondition(const char* conditionName, const char* errorType, const char* fileName, int lineNumber);

#endif
